.TH "ggiDBGetNumBuffers" 3 "2007-12-17" "libggi-current" GGI
.SH NAME
\fBggiDBGetNumBuffers\fR, \fBggiDBGetBuffer\fR : Get DirectBuffers from a visual
.SH SYNOPSIS
.nb
.nf
#include <ggi/ggi.h>

int  ggiDBGetNumBuffers(ggi_visual_t vis);

const ggi_directbuffer *ggiDBGetBuffer(ggi_visual_t vis, int bufnum);
.fi

.SH DESCRIPTION
Dependent on the visual and runtime environment found, applications
may be granted direct access to hardware and/or library internal
buffers. This may significantly enhance performance for certain pixel
oriented applications or libraries.

The DirectBuffer is a mechanism in which a LibGGI program can use to
determine all the characteristics of these buffers (typically the
framebuffer), including the method of addressing, the stride,
alignment requirements, and endianness.

However, use not conforming to this specification will have undefined
effects and may cause data loss or corruption, program malfunction or
abnormal program termination. So you don't really want to do this.

\fBggiDBGetNumBuffers\fR returns the number of DirectBuffers available to
the application.  \fBggiDBGetBuffer\fR obtains the DirectBuffer at the
specified position.

Use \fBggiDBGetBuffer\fR to obtain the DirectBuffers at 0 to n-1, where n
is the number returned by \fBggiDBGetNumBuffers\fR.

Pixel-linear buffers have \f(CWtype==GGI_DB_SIMPLE_PLB | GGI_DB_NORMAL\fR.
You're on your own now.

DirectBuffers where \fBggiResourceMustAcquire(3)\fR is true need to be
'acquired' (i.e. locked) before using.  An acquire is done by using
\fBggiResourceAcquire(3)\fR and is released by calling \fBggiResourceRelease(3)\fR.
Beware that the \fBread\fR, \fBwrite\fR and \fBstride\fR fields of the
DirectBuffer may be changed by an acquire, and that they may be \fBNULL\fR
or invalid when the DirectBuffer is not acquired.
.SH RETURN VALUE
\fBggiDBGetNumBuffers\fR returns the number of DirectBuffers
available. \fB0\fR indicates that no DirectBuffers are available.

\fBggiDBGetBuffer\fR returns a pointer to a DirectBuffer structure.
.SH TYPES OF BUFFERS
Only the framebuffer is defined currently. Other types of buffers,
such as stencil, z will be defined by appropriate GGI extensions.

A frame buffer may be organized as several distinct buffers.  Each
buffer may have a different layout. This means both the addressing
scheme to be used as well as the addressing parameters may differ from
buffer to buffer.

A framebuffer is denoted by \fBggi_directbuffer.type`==`GGI_DB_NORMAL\fR.
Each frame has its own buffer, and its number is indicated in
\fBggi_directbuffer.frame\fR.
.SH EXAMPLES
How to obtain a DirectBuffer:

.nb
.nf
ggi_visual_t  vis;
ggi_mode      mode;
int           i;

/* Framebuffer info */
unsigned char *fbptr[2];
int stride[2];
int numbufs;

mode.frames = 2;      /* Double-buffering */
mode.visible.x = 640; /* Screen res */
mode.visible.y = 480;
mode.virt.x = GGI_AUTO; /* Any virtual resolution.  Will usually be set */
mode.virt.y = GGI_AUTO; /* to be the same as visible but some targets */
                        /* may have restrictions on virtual size. */
mode.graphtype = GT_8BIT;             /* Depend on 8-bit palette. */
mode.dpp.x = mode.dpp.y = GGI_AUTO;   /* Always 1x1 but we don't care. */

if(ggiInit()) {
      /* Failed to initialize library. Bomb out. */
}

vis = ggiOpen(NULL);
if(!vis) {
      /* Opening default visual failed, quit. */
}

if(ggiSetMode(vis, &mode)) {
      /* Set mode has failed, should check if suggested mode
         is o.k. for us, and try the call again. */
}

numbufs = ggiDBGetNumBuffers(vis);

for(i = 0; i < numbufs; i++) {
      ggi_directbuffer *db;
      int frameno;

      db = ggiDBGetBuffer(vis, i);

      if(!(db->type & GGI_DB_SIMPLE_PLB))
      {
              /* We don't handle anything but simple pixel-linear buffers.
                 Fall back to ggiPutBox() or something. */
              continue;
      }

      frameno = db->frame;

      if(readptr[frameno] != NULL &&
              (db->buffer.plb.pixelformat->flags & GGI_PF_REVERSE_ENDIAN))
      {
              continue;
      }

      fbptr[frameno] = db->write;     /* read == write for simple plbs */

      /* Stride of framebuffer (in bytes). */
      stride[frameno] = db->buffer.plb.stride;

      /* Check pixel format, be portable... */
.fi

.SH SEE ALSO
\f(CWggi_directbuffer(3)\fR, \f(CWggiResourceAcquire(3)\fR
